/**
 * 检测管理器 - 负责人物检测相关功能
 */
import type { DetectionArea } from '../../types'
import { PoseDetectionService, type PoseDetectionResult, type PoseDetectionState } from '../../features/mediapipe-pose/PoseDetectionService'
import { DEFAULT_POSE_DETECTION_INTERVAL } from '../../config/mediapipe'

export class DetectionManager {
  private video: HTMLVideoElement | null
  private enableDetection: boolean
  private detectionCache: Map<number, DetectionArea[]> = new Map()
  private detectionInterval = DEFAULT_POSE_DETECTION_INTERVAL
  private cacheMaxSize = 50
  
  // MediaPipe Pose 检测相关
  private poseDetectionService: PoseDetectionService | null = null
  private poseDetectionResult: PoseDetectionResult | null = null
  private poseDetectionInFlight: Promise<PoseDetectionResult> | null = null
  private poseDetectionTimestamp = 0
  
  // 备用策略
  private detectionFailures = 0
  private maxFailures = 3
  private useFallback = false

  constructor(
    video: HTMLVideoElement | null,
    enableDetection: boolean
  ) {
    this.video = video
    this.enableDetection = enableDetection
  }

  /**
   * 设置 MediaPipe Pose 检测（非阻塞）
   */
  setupPoseDetection(): void {
    if (!this.enableDetection || !this.video) {
      return
    }

    // console.log('🚀 开始设置 MediaPipe Pose 检测（后台加载）...')
    this.poseDetectionService = new PoseDetectionService()
    
    this.poseDetectionService.initialize().then(() => {
      // console.log('✅ MediaPipe Pose 检测初始化成功')
      }).catch((_error) => {
      // console.warn('⚠️ MediaPipe Pose 检测初始化失败，将使用模拟检测:', error)
      this.poseDetectionService = null
    })
  }

  /**
   * 处理 Pose 检测
   */
  async processPoseDetection(timestamp: number): Promise<DetectionArea[]> {
    if (!this.video || !this.enableDetection) {
      return []
    }

    // 检查缓存
    const cached = this.getCachedDetection(timestamp)
    if (cached) {
      return cached
    }

    // 检测间隔控制
    if (timestamp - this.poseDetectionTimestamp < this.detectionInterval) {
      return this.poseDetectionResult?.areas || this.getSimulatedDetectionAreas()
    }

    // MediaPipe 检测
    if (this.poseDetectionService) {
      try {
        if (!this.poseDetectionInFlight) {
          this.poseDetectionInFlight = this.poseDetectionService.detect(this.video, timestamp)
        }

        const result = await this.poseDetectionInFlight
        this.poseDetectionResult = result
        this.poseDetectionInFlight = null
        this.poseDetectionTimestamp = timestamp
        
        this.cacheDetection(timestamp, result.areas)
        this.onDetectionSuccess()
        return result.areas
      } catch (error) {
        // console.warn('MediaPipe 检测失败:', error)
        this.poseDetectionInFlight = null
        this.onDetectionFailure()
      }
    }

    // 回退到模拟检测
    const fallbackAreas = this.getFallbackAreas()
    this.cacheDetection(timestamp, fallbackAreas)
    return fallbackAreas
  }

  /**
   * 获取缓存的检测结果
   */
  private getCachedDetection(timestamp: number): DetectionArea[] | null {
    const cacheKey = Math.floor(timestamp / 1000) * 1000
    return this.detectionCache.get(cacheKey) || null
  }

  /**
   * 缓存检测结果
   */
  private cacheDetection(timestamp: number, areas: DetectionArea[]): void {
    const cacheKey = Math.floor(timestamp / 1000) * 1000
    
    if (this.detectionCache.size >= this.cacheMaxSize) {
      const firstKey = this.detectionCache.keys().next().value as number
      if (firstKey !== undefined) {
        this.detectionCache.delete(firstKey)
      }
    }
    
    this.detectionCache.set(cacheKey, areas)
  }

  /**
   * 检测成功回调
   */
  private onDetectionSuccess(): void {
    if (this.useFallback) {
      this.useFallback = false
      this.detectionFailures = 0
      // console.log('✅ 检测恢复正常')
    }
  }

  /**
   * 检测失败回调
   */
  private onDetectionFailure(): void {
    this.detectionFailures++
    if (this.detectionFailures >= this.maxFailures && !this.useFallback) {
      this.useFallback = true
      // console.warn(`⚠️ 检测连续失败 ${this.maxFailures} 次，切换到备用模式`)
    }
  }

  /**
   * 获取备用检测区域
   */
  private getFallbackAreas(): DetectionArea[] {
    return this.useFallback ? this.getSimulatedDetectionAreas() : []
  }

  /**
   * 获取模拟检测区域
   */
  getSimulatedDetectionAreas(): DetectionArea[] {
    if (!this.video) return []

    const canvas = document.createElement('canvas')
    const videoRect = this.video.getBoundingClientRect()
    canvas.width = videoRect.width
    canvas.height = videoRect.height

    return [
      {
        left: canvas.width * 0.35,
        right: canvas.width * 0.65,
        top: canvas.height * 0.15,
        bottom: canvas.height * 0.85
      }
    ]
  }

  /**
   * 重新加载 Pose 检测
   */
  reloadPoseDetection(): void {
    if (!this.video) return
    
    // console.log('🔄 重新加载 MediaPipe Pose 检测...')
    
    if (this.poseDetectionService) {
        this.poseDetectionService.close().catch((_err) => {
        // console.warn('清理旧检测服务时出错:', err)
      })
    }
    
    this.poseDetectionResult = null
    this.poseDetectionInFlight = null
    this.poseDetectionTimestamp = 0
    this.poseDetectionService = null
    
    this.setupPoseDetection()
  }

  /**
   * 获取 Pose 检测状态
   */
  getPoseDetectionState(): PoseDetectionState {
    if (!this.poseDetectionService) {
      return {
        initialized: false,
        initializing: false,
        modelLoaded: false,
        runningMode: 'VIDEO',
        error: undefined,
      }
    }
    return this.poseDetectionService.getState()
  }

  /**
   * 清理资源
   */
  async destroy(): Promise<void> {
    this.detectionCache.clear()
    if (this.poseDetectionService) {
      await this.poseDetectionService.close()
      this.poseDetectionService = null
    }
  }
}

